import random

num = 4
recommended_race_time = 2


# 定义结构体
class Node(object):
    def __init__(self, index):
        self.i = index
        self.racedTimes = 0
        self.racedTeams = []
        self.usedCountry = []


class Race(object):
    def __init__(self, index):
        self.i = index
        self.Teams = [0, 0, 0, 0, 0]


# 初始化
allowed_race_time = recommended_race_time
nodes = [Node(0)]
for i in range(num):
    nodes.append(Node(i + 1))
races = []
racePointer = 0
loopPointer = 1
# 安排赛事
for i in range(num):
    # 计算当前贪心安排的队伍编号
    teamID = i + 1
    # print("处理队伍" + str(teamID))
    # 队伍已经比过两次则继续处理下一个队伍
    if nodes[teamID].racedTimes >= recommended_race_time:
        # print("队伍" + str(teamID) + "已有多场比赛，跳过，比赛场数=" + str(nodes[teamID].racedTimes))
        continue
    # print("队伍需要增添赛事：" + str(teamID) + "，当前赛事数：" + str(nodes[teamID].racedTimes))
    # 安排赛事直到当前队伍有两场比赛
    while nodes[teamID].racedTimes < recommended_race_time:
        # 新建赛事
        race = Race(racePointer)
        racePointer += 1
        # 为当前贪心安排的队伍随机分配一个未使用过的国家
        reRandom = True
        rd = 0
        loopT = 0
        while reRandom:
            reRandom = False
            loopT += 1
            # 如果摇不到空位就算了
            if loopT > 100:
                continue
            rd = random.randint(1, 4)
            for q in range(len(nodes[teamID].usedCountry)):
                if rd == nodes[teamID].usedCountry[q]:
                    reRandom = True
        race.Teams[rd] = teamID
        # 使用loopPointer填充剩余的三个对手国家
        for j in range(4):
            # 填充对手国家
            if race.Teams[j + 1] == 0:
                # 使用while循环控制loopPointer指向最近的适宜队伍
                loopTimes = 0
                need_to_ctn = True
                while need_to_ctn:
                    need_to_ctn = False
                    # 自增loopPointer并循环
                    loopPointer += 1
                    if loopPointer > num:
                        loopPointer = 1
                    # 检查是否多次循环，需要执行队伍复用
                    loopTimes += 1
                    if loopTimes > 2 * num:
                        print("警告：遍历了两遍找不到可以安排的队伍，将进行队伍复用，贪心队伍=" + str(teamID))
                        print("当前队伍复用次数为" + str(allowed_race_time - recommended_race_time))
                        allowed_race_time += 1
                        loopPointer = 1
                        break
                    # 拦截比赛次数过多的队伍
                    if nodes[loopPointer].racedTimes >= allowed_race_time:
                        need_to_ctn = True
                        continue
                    # 拦截与自己比赛
                    if loopPointer == teamID:
                        need_to_ctn = True
                        continue
                    # 拦截已被安排为对手的队伍
                    for n in range(4):
                        if loopPointer == race.Teams[n + 1]:
                            need_to_ctn = True
                            break
                    if need_to_ctn:
                        continue
                    # 如果已经与在场的已安排好的所有人中的其中一个比过则拦截
                    for o in range(4):
                        if race.Teams[o + 1] == 0:
                            continue
                        for n in range(len(nodes[race.Teams[o + 1]].racedTeams)):
                            if loopPointer == nodes[race.Teams[o + 1]].racedTeams[n]:
                                need_to_ctn = True
                                break
                    if need_to_ctn:
                        continue
                    # 如果已经使用过了该国家的代码则拦截
                    for q in range(len(nodes[loopPointer].usedCountry)):
                        if nodes[loopPointer].usedCountry[q] == j + 1:
                            need_to_ctn = True
                            continue
                    if need_to_ctn:
                        continue
                # print("推进查找完成")
                # 使用loopPointer指向的国家
                race.Teams[j + 1] = loopPointer
        # 为已经上位的4位修改node信息
        for j in range(4):
            nodes[race.Teams[j + 1]].racedTimes += 1
            for k in range(4):
                if j == k or race.Teams[k + 1] == 0:
                    continue
                nodes[race.Teams[j + 1]].racedTeams.append(race.Teams[k + 1])
            nodes[race.Teams[j + 1]].usedCountry.append(j + 1)
        # 将赛事推入赛事数组
        races.append(race)
        print("赛事安排完毕，贪心队伍为" + str(teamID))
        print("Teams=" + str(race.Teams[1]) + "," + str(race.Teams[2]) + "," + str(race.Teams[3]) + "," + str(
            race.Teams[4]))
        for m in range(4):
            tid = race.Teams[m + 1]
            # print("队伍" + str(tid) + "的racedTimes=" + str(nodes[tid].racedTimes))
    print(nodes[i].usedCountry)
print("队伍复用总次数为" + str(allowed_race_time - recommended_race_time))
# 校验比赛公平性
print("——————————————")
for i in range(num):
    teamID = i + 1
    # 校验超过推荐比赛场数的队伍
    if nodes[teamID].racedTimes > recommended_race_time:
        print("校验警告：队伍" + str(teamID) + "的比赛场数超过了推荐次数，实际次数为" + str(nodes[teamID].racedTimes))
    # 校验记录的对手数据是否有误
    if nodes[teamID].racedTimes * 3 != len(nodes[teamID].racedTeams):
        print("！校验错误：队伍" + str(teamID) + "的对手记录错误")
    # 校验是否与自己比赛
    repeatChecked = False
    for m in range(len(nodes[teamID].racedTeams)):
        if nodes[teamID].racedTeams[m] == teamID:
            print("！校验错误：队伍" + str(teamID) + "与自己比赛")
    # 校验是否存在多次的相同对手
    for m in range(len(nodes[teamID].racedTeams)):
        for n in range(m):
            if m == n:
                continue
            if nodes[teamID].racedTeams[m] == nodes[teamID].racedTeams[n]:
                print("！校验错误：队伍" + str(teamID) + "出现了多次的相同对手：" + str(nodes[teamID].racedTeams[n]))
                '''for f in range(len(nodes[teamID].racedTeams)):
                    print(nodes[teamID].racedTeams[f])'''
                repeatChecked = True
                break
        if repeatChecked:
            break
    # 校验国家是否出现重用
    for m in range(len(nodes[teamID].usedCountry)):
        for n in range(m-1):
            if nodes[teamID].usedCountry[m]==nodes[teamID].usedCountry[n]:
                print("！校验错误：队伍" + str(teamID) + "出现了同国家代码的多次调用")
print("公平性校验结束")
print("——————————————")
# 输出比赛安排
print("一共安排了" + str(len(races)) + "场比赛，具体情况如下：")
for i in range(len(races)):
    print(str(i) + ". " + str(races[i].Teams[1]) + "," + str(races[i].Teams[2]) + "," + str(
        races[i].Teams[3]) + "," + str(races[i].Teams[4]))
